package com.dlc.shop.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dlc.shop.bean.app.dto.ProductDto;
import com.dlc.shop.bean.enums.ProdType;
import com.dlc.shop.bean.model.Category;
import com.dlc.shop.bean.model.ProdBrowseLog;
import com.dlc.shop.bean.model.ProdLang;
import com.dlc.shop.bean.model.Product;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.util.PageParam;
import com.dlc.shop.dao.ProdBrowseLogMapper;
import com.dlc.shop.manager.impl.LangManager;
import com.dlc.shop.service.CategoryService;
import com.dlc.shop.service.ProdBrowseLogService;
import com.dlc.shop.service.ProductService;
import lombok.AllArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 商品浏览记录表
 *
 * @author LGH
 * @date 2021-11-01 10:43:09
 */
@Service
@AllArgsConstructor
public class ProdBrowseLogServiceImpl extends ServiceImpl<ProdBrowseLogMapper, ProdBrowseLog> implements ProdBrowseLogService {

    private final ProdBrowseLogMapper prodBrowseLogMapper;
    private final ProductService productService;
    private final CategoryService categoryService;
    private final LangManager langManager;

    @Override
    public IPage<ProdBrowseLog> pageByUserId(PageParam<ProductDto> page, String userId) {
        IPage<ProdBrowseLog> prodBrowseLogPage = prodBrowseLogMapper.pageByUserId(page, userId);
        if (CollUtil.isEmpty(prodBrowseLogPage.getRecords())) {
            return prodBrowseLogPage;
        }
        List<Long> ids = prodBrowseLogPage.getRecords().stream().map(ProdBrowseLog::getProdId).filter(prodId -> Objects.nonNull(prodId)).collect(Collectors.toList());
        Map<Long, ProdLang> prodLangMap = langManager.getProdLangMap(ids);
        for (ProdBrowseLog prodBrowseLog : prodBrowseLogPage.getRecords()) {
            ProdLang prodLang = prodLangMap.get(prodBrowseLog.getProdId());
            if (Objects.nonNull(prodLang)) {
                prodBrowseLog.setProdName(prodLang.getProdName());
            }
        }
        return prodBrowseLogPage;
    }

    @Override
    public void saveInfo(ProdBrowseLog prodBrowseLog) {
        if (Objects.isNull(prodBrowseLog.getProdType())) {
            prodBrowseLog.setProdType(ProdType.PROD_TYPE_NORMAL.value());
        }
        Date now = new Date();
        long count = prodBrowseLogMapper.selectCount(Wrappers.lambdaQuery(ProdBrowseLog.class)
                .eq(ProdBrowseLog::getUserId, prodBrowseLog.getUserId())
                .eq(ProdBrowseLog::getBrowseTime, DateUtil.beginOfDay(now))
                .eq(ProdBrowseLog::getProdId, prodBrowseLog.getProdId())
        );
        if (count == 0) {
            Product product = productService.getProductByProdId(prodBrowseLog.getProdId());
            if (Objects.nonNull(product)) {
                prodBrowseLog.setShopId(product.getShopId());
            }
            List<Category> categoryAndParent = categoryService.getCategoryAndParent(product.getCategoryId());
            if (product.getShopId() != Constant.PLATFORM_SHOP_ID) {
                prodBrowseLog.setCategoryId(categoryAndParent.get(0).getCategoryId());
            }
            prodBrowseLog.setProdType(product.getProdType());
            prodBrowseLog.setCreateTime(now);
            prodBrowseLog.setBrowseTime(DateUtil.beginOfDay(now));
            try {
                prodBrowseLog.setBrowseTime(DateUtil.parseDate(DateUtil.formatDate(now)));
                prodBrowseLogMapper.insert(prodBrowseLog);
                return;
            } catch (Exception e) {
                // 如果不是重复插入报错就抛出异常，重复插入报错不用处理，在下面执行更新操作
                if (!(e instanceof DuplicateKeyException)) {
                    throw new YamiShopBindException(e.getMessage());
                }
            }
        }
        if (count == 1){
            ProdBrowseLog dbLog = prodBrowseLogMapper.selectOne(Wrappers.lambdaQuery(ProdBrowseLog.class)
                    .eq(ProdBrowseLog::getUserId, prodBrowseLog.getUserId())
                    .eq(ProdBrowseLog::getBrowseTime, DateUtil.beginOfDay(now))
                    .eq(ProdBrowseLog::getProdId, prodBrowseLog.getProdId()));
            dbLog.setCreateTime(now);
            prodBrowseLogMapper.updateById(dbLog);
        }
    }

    @Override
    public void deleteByIds(List<Long> prodBrowseLogIds, String userId) {
        prodBrowseLogMapper.delete(Wrappers.lambdaQuery(ProdBrowseLog.class)
                .in(ProdBrowseLog::getProdBrowseLogId, prodBrowseLogIds)
                .eq(ProdBrowseLog::getUserId, userId)
        );
    }
    @Override
    public Long recommendCategoryId(Integer prodType, String userId) {
        if (Objects.isNull(prodType)) {
            prodType = ProdType.PROD_TYPE_NORMAL.value();
        }
        return prodBrowseLogMapper.recommendCategoryId(prodType, userId, Constant.MAX_PROD_BROWSE_NUM);
    }
}
